package com.qiaofang.collectmanage.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created with IDEA 日期时间工具类
 *
 * @author:ZJ.J
 * @Date:2018/5/29
 * @Time:9:38
 */
public class DateUtils {

    private static final Logger logger = LoggerFactory.getLogger(DateUtils.class);

    public static final String MM_DD = "MM-dd";
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYY_MM_DD2 = "yyyy年MM月dd日";
    public static final String YYYY_MM_DD3 = "yyyy/MM/ddHH:mm:ss";
    public static final String YYYY_MM_DD4 = "yyyy-MM-ddHH:mm";
    public static final String YYYY_MM_DD5 = "yyyy-MM-ddHH:mm:ss";
    public static final String YYYY_MM_DD_T_HH_MM_SS_SSSZ = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";

    public static final Pattern p = Pattern.compile("\\s*|\t|\r|\n");

    /**
     * 将时间转成带时区的
     * @param updateTime
     * @return
     */
    public long parseDateWithTimeZone(String updateTime)throws ParseException{
       long updateTimeWithZone = DateUtils.parseInputDateStr(updateTime, DateUtils.YYYY_MM_DD_T_HH_MM_SS_SSSZ).getTime();
       return updateTimeWithZone;
    }
    /**
     * 根据指定格式格式化时间
     *
     * @param date
     * @param outputFormat
     * @return
     */
    public static String format(Date date, String outputFormat) {
        SimpleDateFormat fm = new SimpleDateFormat(outputFormat);
        return fm.format(date.getTime());
    }

    /**
     * 根据输入时间格式转换为指定的格式
     *
     * @param inputStr     输入时间字符 2018-05-25、2018年05月25日、05-10
     * @param inputFormat  输入时间字符格式
     * @param outputFormat 输出时间字符格式
     * @return
     * @throws Exception
     */
    public static String parseInputDateStr(String inputStr, String inputFormat, String outputFormat) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(outputFormat);
        SimpleDateFormat parse = new SimpleDateFormat(inputFormat);
        return format.format(parse.parse(inputStr));
    }

    public static Date parseInputDateStr(String inputStr, String inputFormat) throws ParseException {
        SimpleDateFormat parse = new SimpleDateFormat(inputFormat);
        return parse.parse(inputStr);
    }

    /**
     * 更新时间年份
     *
     * @param inputStr
     * @param inputFormat
     * @param outputFormat
     * @return
     * @throws ParseException
     */
    public static String updateDateYear(String inputStr, String inputFormat, String outputFormat) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat(outputFormat);
        SimpleDateFormat parse = new SimpleDateFormat(inputFormat);
        Date date = parse.parse(inputStr);
        Calendar calendar = Calendar.getInstance();
        int yaer = calendar.get(Calendar.YEAR);
        calendar.setTime(date);
        calendar.set(Calendar.YEAR, yaer);
        return format.format(calendar.getTime());
    }

    /**
     * 获取当前时间,格式换为指定的字符串 今天
     *
     * @return
     */
    public static String currentTime(String formatStr) {
        SimpleDateFormat fm = new SimpleDateFormat(formatStr);
        return fm.format(new Date());
    }

    /**
     * 几天前，几天后  一天前
     *
     * @param i           i为正数几天后，i为负数几天前
     * @param outputFomat 输出时间字符格式
     * @return
     * @throws ParseException
     */
    public static String addDays(int i, String outputFomat) throws ParseException {
        Date endDate = org.apache.commons.lang3.time.DateUtils.addDays(new Date(), i);
        return DateFormatUtils.format(endDate, outputFomat);
    }

    /**
     * 几小时前，几小时后  3小时前
     *
     * @param i           i为正数几小时后，i为负数几小时前
     * @param outputFomat 输出时间字符格式
     * @return
     * @throws ParseException
     */
    public static String addHours(int i, String outputFomat) throws ParseException {
        Date endDate = org.apache.commons.lang3.time.DateUtils.addHours(new Date(), i);
        return DateFormatUtils.format(endDate, outputFomat);
    }

    /**
     * 几分钟前，几分钟后  3分钟前
     *
     * @param i           i为正数几分钟后，i为负数几分钟前
     * @param outputFomat 输出时间字符格式
     * @return
     * @throws ParseException
     */
    public static String addMinutes(int i, String outputFomat) throws ParseException {
        Date endDate = org.apache.commons.lang3.time.DateUtils.addMinutes(new Date(), i);
        return DateFormatUtils.format(endDate, outputFomat);
    }


    /**
     * 解析爬虫publishTime
     *
     * @param inputStr     输入时间字符串 null、""、今天、3分钟前、3小时前、3天前、一天前、05-29、2018-05-29、2018年05月29日
     * @param outputFormat 输出时间字符格式
     * @return
     */
    public static String parsePublishTime(String inputStr, String outputFormat) {
        //为采集到publistTime 默认为三天前
        String formatStr;
        try {
            formatStr = addDays(-3, outputFormat);
            if (StringUtils.isNotBlank(inputStr)) {
                if (!(inputStr.trim().split("/").length > 1)) {
                    inputStr = inputStr.replaceAll(" ", "");
                    inputStr = replaceBlank(inputStr);
                }

                //今天
                if (inputStr.contains("今天")) {
                    formatStr = currentTime(outputFormat);
                }
                //3分钟前
                if (inputStr.contains("分钟前")) {
                    String num = RegExUtils.getNum(inputStr.trim());
                    formatStr = addMinutes(-Integer.valueOf(num), outputFormat);
                }
                //3小时前
                if (inputStr.contains("小时前")) {
                    String num = RegExUtils.getNum(inputStr.trim());
                    formatStr = addHours(-Integer.valueOf(num), outputFormat);
                }
                //3天前
                if (inputStr.contains("天前")) {
                    if (inputStr.contains("一")) {
                        formatStr = addDays(-1, outputFormat);
                    } else {
                        String num = RegExUtils.getNum(inputStr.trim());
                        formatStr = addDays(-Integer.valueOf(num), outputFormat);
                    }
                }
                //05-29
                if (inputStr.trim().length() == 5 && inputStr.trim().split("-").length == 2) {
                    String tmpDateStr = parseInputDateStr(inputStr, MM_DD, outputFormat);
                    formatStr = updateDateYear(tmpDateStr, outputFormat, outputFormat);
                }
                //2018-05-29
                if (inputStr.trim().length() == 10 && inputStr.trim().split("-").length == 3) {
                    formatStr = parseInputDateStr(inputStr, YYYY_MM_DD, outputFormat);
                }
                //2018年05月29日
                if (inputStr.trim().length() == 11 && inputStr.trim().contains("年") && inputStr.trim().contains("月") && inputStr.trim().contains("日")) {
                    formatStr = parseInputDateStr(inputStr, YYYY_MM_DD2, outputFormat);
                }
                //2018/05/2914:05:00
                if (inputStr.trim().split("/").length == 3 && inputStr.trim().split(":").length == 3) {
                    formatStr = parseInputDateStr(inputStr, YYYY_MM_DD3, outputFormat);
                }
                //2018-05-29 44:44
                if (inputStr.trim().split("-").length == 3 && inputStr.trim().split(":").length == 2) {
                    formatStr = parseInputDateStr(inputStr, YYYY_MM_DD4, outputFormat);
                }
                //2018-05-29 44:44:33
                if (inputStr.trim().split("-").length == 3 && inputStr.trim().split(":").length == 3) {
                    formatStr = parseInputDateStr(inputStr, YYYY_MM_DD5, outputFormat);
                }
            }
        } catch (Exception e) {
            logger.error("time:{}", e);
            formatStr = currentTime(outputFormat);
        }

        return formatStr;
    }

    public static void main(String[] args) throws Exception {
        //null
        System.out.println("null             :" + parsePublishTime(null, YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // ""
        System.out.println("                    :" + parsePublishTime("", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 今天
        System.out.println("今天                :" + parsePublishTime("今天", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 3分钟前
        System.out.println("3分钟前             :" + parsePublishTime("3分钟前", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 3小时前
        System.out.println("3小时前             :" + parsePublishTime("3小时前", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 3天前
        System.out.println("3天前               :" + parsePublishTime("3天前", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 一天前
        System.out.println("一天前              :" + parsePublishTime("一天前", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 05-29
        System.out.println("05-29              :" + parsePublishTime("05-29", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 2018-05-29
        System.out.println("2018-05-29         :" + parsePublishTime("2018-05-29", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 2018年05月29日
        System.out.println("2018年05月29日      :" + parsePublishTime("2018年05月29日", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        // 2018年05月29日
        System.out.println("2018年05月29日      :" + parsePublishTime("2018年05月29日", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
        //2018/05/2914:05:00
        System.out.println("2018/05/2914:05:00 :" + parsePublishTime("2018/05/2914:05:00", YYYY_MM_DD_T_HH_MM_SS_SSSZ));
    }

    /**
     * @param str
     * @return
     * @desc 替换空格
     */
    public static String replaceBlank(String str) {
        String dest = null;
        if (str == null) {
            return dest;
        } else {
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
            //特殊字符
            dest = dest.replaceAll("　", "");
            return dest;
        }
    }
}
